import 'dart:io';

import 'package:dartkit/dartkit.dart';

class Shell {
  // 清空shell屏幕，相当于cmd+K
  // 由于它涉及到shell的行为，因此很难写单元测试（主要是不知道Windows上的表现）
  // 暂时决定跳过单元测试
  static void clear() {
    // AI写的，我不用windows暂时不了解
    if (Platform.isWindows) {
      print(Process.runSync("cls", [], runInShell: true).stdout);
    } else {
      // ANSI转义序列，暂时看成一串咒语就可以了
      stdout.write("\x1B[2J\x1B[0;0H");
      stdout.flush();
    }
  }

  /// 让用户输入一些文字，并返回结果
  static String getInput({required String prompt}) {
    print(prompt);
    String? input = stdin.readLineSync();
    if (input == null) throw "无法正常读取input";
    return input;
  }

  /// 让用户输入一个整数
  static int getInputInt({required String prompt}) {
    String input = getInput(prompt: prompt);
    return int.parse(input);
  }

  /// 让用户输入一个整数
  static double getInputDouble({required String prompt}) {
    String input = getInput(prompt: prompt);
    return double.parse(input);
  }

  /// 用户将文件夹拖到窗口中，按回车键，实际上是提交了文件夹所在的路径
  /// 根据路径找到对应的文件夹
  static Directory dragDirectory() {
    // 提取path字符串
    String path = getInput(prompt: "请将目标文件夹拖入到当前窗口，并按回车键继续");

    // 直接拖入的路径可能会有各种错误，因此需要先进行修饰后，才能传入到Directory中
    // 去除头尾的引号
    if (path.startsWith("'") && path.endsWith("'")) {
      path = path.substring(1, path.length - 1);
    } else if (path.startsWith('"') && path.endsWith('"')) {
      path = path.substring(1, path.length - 1);
    }
    // 去除转义符
    path = path.replaceAll("\\", '');
    // 去除头尾空格
    path = path.trim();

    return Directory(path);
  }

  /// 用户将文件夹拖到窗口中，按回车键，实际上是提交了文件夹所在的路径
  /// 根据路径找到对应的文件夹
  static String dragPath() {
    // 提取path字符串
    String path = getInput(prompt: "请将目标文件拖入到当前窗口，并按回车键继续");

    return path;
  }

  /// 使用zsh运行某段代码，如果成功则将输出返回，如果失败，则用Bug的形式throw出来
  /// 如果是在MacOS中，有时候这个行为会触发沙盒的警报
  static Future<String> runZsh(String command) async {
    // 将command前面加上source源
    String concat = "source ~/.zshrc && $command";

    // 由于dart中默认用bash，因此需要修改默认行为
    final result = await Process.run(
      "/bin/zsh",
      ["-c", concat],
      runInShell: true,
    );

    // 如果没有成功，则throw为Bug
    if (result.exitCode != 0) throw Bug(result.stderr);

    // 如果成功了，则返回stdout
    return result.stdout;
  }
}

void exitWithError(String reason) {
  print(reason);
  exit(1);
}
